package com.test.springboot.springboot3testdemo3.utils;

import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * 增强型线程工厂，提供以下功能： 1. 自定义线程命名 2. 异常处理机制 3. 线程优先级和守护状态设置 4. 线程池监控及指标收集 5. 资源自动管理
 *
 * @author： liuziyang
 * @since： 2025/3/11-09:34
 * @version: 1.1
 */
public class EnhancedThreadFactory implements ThreadFactory, AutoCloseable {
  private static final Logger LOGGER = Logger.getLogger(EnhancedThreadFactory.class.getName());
  private static final AtomicInteger poolNumber = new AtomicInteger(1);
  private final ThreadGroup group;
  private final AtomicInteger threadNumber = new AtomicInteger(1);
  private final String namePrefix;
  private final Consumer<Throwable> exceptionHandler;
  private final boolean daemon;
  private final int priority;

  /** 监控相关字段 */
  private final ThreadPoolExecutor monitoredExecutor;

  private final ScheduledExecutorService monitorScheduler;
  private ScheduledFuture<?> monitorTask;

  /** 队列大小告警阈值 */
  private final int queueSizeWarningThreshold;

  /** 活跃线程比例告警阈值(百分比) */
  private final int activeThreadRatioWarningThreshold;

  private final MetricsCollector metricsCollector;

  private EnhancedThreadFactory(Builder builder) {
    SecurityManager s = System.getSecurityManager();
    group = (s != null) ? s.getThreadGroup() : Thread.currentThread().getThreadGroup();
    namePrefix = builder.namePrefix + "-pool-" + poolNumber.getAndIncrement() + "-thread-";
    exceptionHandler =
        builder.exceptionHandler != null
            ? builder.exceptionHandler
            : throwable -> LOGGER.log(Level.SEVERE, "未捕获异常", throwable);
    daemon = builder.daemon;
    priority = builder.priority;
    monitoredExecutor = builder.monitoredExecutor;
    queueSizeWarningThreshold = builder.queueSizeWarningThreshold;
    activeThreadRatioWarningThreshold = builder.activeThreadRatioWarningThreshold;
    metricsCollector = builder.metricsCollector;

    // 初始化监控(如果需要)
    if (builder.enableMonitoring && builder.monitoredExecutor != null) {
      monitorScheduler =
          Executors.newSingleThreadScheduledExecutor(
              new NamedThreadFactory(builder.namePrefix + "-monitor"));
      startMonitoring(builder.monitoringInterval);
    } else {
      monitorScheduler = null;
    }
  }

  @Override
  public Thread newThread(Runnable r) {
    Runnable taskWithExceptionHandling =
        () -> {
          try {
            r.run();
          } catch (Throwable t) {
            exceptionHandler.accept(t);
          }
        };

    Thread t =
        new Thread(
            group, taskWithExceptionHandling, namePrefix + threadNumber.getAndIncrement(), 0);
    t.setDaemon(daemon);
    t.setPriority(priority);
    return t;
  }

  /**
   * 启动线程池监控，定期收集统计数据
   *
   * @param intervalSeconds 监控间隔(秒)
   */
  private void startMonitoring(long intervalSeconds) {
    if (monitorScheduler != null && monitoredExecutor != null) {
      monitorTask =
          monitorScheduler.scheduleAtFixedRate(
              this::collectAndReportPoolStats, 0, intervalSeconds, TimeUnit.SECONDS);
    }
  }

  /** 收集并报告线程池统计数据 当达到告警阈值时，会提升日志级别为WARNING */
  private void collectAndReportPoolStats() {
    if (monitoredExecutor == null) return;

    int activeCount = monitoredExecutor.getActiveCount();
    int corePoolSize = monitoredExecutor.getCorePoolSize();
    int maxPoolSize = monitoredExecutor.getMaximumPoolSize();
    int poolSize = monitoredExecutor.getPoolSize();
    long completedTaskCount = monitoredExecutor.getCompletedTaskCount();
    int queueSize = monitoredExecutor.getQueue().size();

    // 计算活跃线程比例
    int activeThreadRatio = poolSize > 0 ? (activeCount * 100 / poolSize) : 0;

    // 检查是否需要告警
    Level logLevel = Level.INFO;
    StringBuilder warnings = new StringBuilder();

    if (queueSize >= queueSizeWarningThreshold) {
      logLevel = Level.WARNING;
      warnings.append("队列积压过多! ");
    }

    if (activeThreadRatio >= activeThreadRatioWarningThreshold) {
      logLevel = Level.WARNING;
      warnings.append("线程池负载过高! ");
    }

    String statsMessage =
        String.format(
            "[%s] 线程池状态: 活跃线程=%d, 核心线程数=%d, 最大线程数=%d, " + "当前线程数=%d, 已完成任务=%d, 队列大小=%d, 活跃比例=%d%%",
            namePrefix,
            activeCount,
            corePoolSize,
            maxPoolSize,
            poolSize,
            completedTaskCount,
            queueSize,
            activeThreadRatio);

    if (warnings.length() > 0) {
      LOGGER.log(logLevel, warnings + statsMessage);
    } else {
      LOGGER.log(logLevel, statsMessage);
    }

    // 收集指标(如果配置了指标收集器)
    if (metricsCollector != null) {
      metricsCollector.collectMetrics(
          namePrefix, activeCount, poolSize, queueSize, completedTaskCount, activeThreadRatio);
    }
  }

  /** 停止监控并释放资源 */
  public void stopMonitoring() {
    if (monitorTask != null) {
      monitorTask.cancel(false);
    }
    if (monitorScheduler != null && !monitorScheduler.isShutdown()) {
      monitorScheduler.shutdown();
      try {
        // 优雅关闭监控器，等待最多5秒
        if (!monitorScheduler.awaitTermination(5, TimeUnit.SECONDS)) {
          monitorScheduler.shutdownNow();
        }
      } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
        monitorScheduler.shutdownNow();
      }
    }
  }

  /** 实现AutoCloseable接口，方便在try-with-resources中使用 */
  @Override
  public void close() {
    stopMonitoring();
  }

  /** 线程池监控指标收集器接口 */
  public interface MetricsCollector {
    /**
     * 收集线程池指标
     *
     * @param poolName 线程池名称
     * @param activeThreads 活跃线程数
     * @param totalThreads 总线程数
     * @param queueSize 队列大小
     * @param completedTasks 已完成任务数
     * @param activeThreadRatio 活跃线程比例(百分比)
     */
    void collectMetrics(
        String poolName,
        int activeThreads,
        int totalThreads,
        int queueSize,
        long completedTasks,
        int activeThreadRatio);
  }

  /** EnhancedThreadFactory构建器 */
  public static class Builder {
    private String namePrefix = "default";
    private Consumer<Throwable> exceptionHandler = null;
    private boolean daemon = false;
    private int priority = Thread.NORM_PRIORITY;
    private ThreadPoolExecutor monitoredExecutor = null;
    private boolean enableMonitoring = false;
    private long monitoringInterval = 60; // 默认60秒
    private int queueSizeWarningThreshold = Integer.MAX_VALUE; // 默认不告警
    private int activeThreadRatioWarningThreshold = 100; // 默认不告警
    private MetricsCollector metricsCollector = null;

    /** 设置线程名称前缀 */
    public Builder namePrefix(String namePrefix) {
      this.namePrefix = namePrefix;
      return this;
    }

    /** 设置异常处理器 */
    public Builder exceptionHandler(Consumer<Throwable> exceptionHandler) {
      this.exceptionHandler = exceptionHandler;
      return this;
    }

    /** 设置是否为守护线程 */
    public Builder daemon(boolean daemon) {
      this.daemon = daemon;
      return this;
    }

    /** 设置线程优先级 */
    public Builder priority(int priority) {
      this.priority = priority;
      return this;
    }

    /** 设置要监控的线程池 */
    public Builder monitorExecutor(ThreadPoolExecutor executor) {
      this.monitoredExecutor = executor;
      return this;
    }

    /** 启用或禁用监控 */
    public Builder enableMonitoring(boolean enableMonitoring) {
      this.enableMonitoring = enableMonitoring;
      return this;
    }

    /** 设置监控间隔时间(秒) */
    public Builder monitoringInterval(long intervalSeconds) {
      this.monitoringInterval = intervalSeconds;
      return this;
    }

    /** 设置队列大小告警阈值 */
    public Builder queueSizeWarningThreshold(int threshold) {
      this.queueSizeWarningThreshold = threshold;
      return this;
    }

    /** 设置活跃线程比例告警阈值(百分比) */
    public Builder activeThreadRatioWarningThreshold(int thresholdPercent) {
      this.activeThreadRatioWarningThreshold = thresholdPercent;
      return this;
    }

    /** 设置指标收集器 */
    public Builder metricsCollector(MetricsCollector collector) {
      this.metricsCollector = collector;
      return this;
    }

    /** 构建EnhancedThreadFactory实例 */
    public EnhancedThreadFactory build() {
      return new EnhancedThreadFactory(this);
    }
  }
}
